<?php
/** 
 * 
 *
 * @package api
 * @subpackage collections
 * @author $Author$
 * @version $Id: Stack.php 14 2006-11-28 22:05:19Z rdff3 $
 */
/**
 *
 */
require_once( "util/ArrayList.php" );
require_once( "util/RandomAccess.php" );
require_once( "lang/Object.php" );

/**
 * Class Stack
 *
 * The Stack class represents a last-in-first-out (LIFO) stack of objects. It extends class ArrayList with four operations that 
 * allow an ArrayList to be treated as a stack. The usual push and pop operations are provided, as well as a method to peek at 
 * the top item on the stack, and a method to search the stack for an item and discover how far it is from the top.
 * 
 * When a stack is first created, it contains no items. 
 *
 * @package api
 * @subpackage collections
 * @author $Author$
 * @version $Id: Stack.php 14 2006-11-28 22:05:19Z rdff3 $
 */
class Stack extends ArrayList implements RandomAccess {
	
	/**
	 * Creates an empty stack
	 */
	public function __construct() {
		parent::__construct();
	}
	
	
	/**
	 * Looks at the object at the top of this stack without removing it from the stack.
	 *
	 * @returns Object The object at the top of this stack (the last item of the ArrayList object).
	 * @throws {@link EmptyStackException} - if this stack is empty.
	 */
	public function peek() {
		if ($this->isEmpty())
			throw new EmptyStackException();
			
		return $this->get( $this->size() - 1 );
	}
	
	/**
	 * Removes the object at the top of this stack and returns that object as the value of this function.
	 *
	 * @returns Object The object at the top of this stack (the last item of the ArrayList object).
	 * @throws {@link EmptyStackException} - if this stack is empty.
	 */
	public function pop() {
		if ($this->isEmpty())
			throw new EmptyStackException();
	
		return $this->removeAt( $this->size() - 1 );
	}
	
	/**
	 * Pushes an item onto the top of this stack. 
	 *
	 * @param Object $item the item to be pushed onto this stack.
	 * @returns Object the $item argument
	 */
	public function push( Object $item ) {
		$this->add( $item );
		return $item;
	}
	
	/**
	 * Returns the 1-based position where an object is on this stack.
	 *
	 * Returns the 1-based position where an object is on this stack. If the object o occurs as an item in this stack, this 
	 * method returns the distance from the top of the stack of the occurrence nearest the top of the stack; the topmost item 
	 * on the stack is considered to be at distance 1. The equals method is used to compare o to the items in this stack.
	 *
	 * @param Object $o the desired object.
	 * @returns int the 1-based position from the top of the stack where the object is located; the return value -1  indicates that the object is not on the stack.
	 */
	public function search( Object $o ) {
		$o_index = $this->indexOf( $o );
		if ($o_index == -1)
			return $o_index;
		else
			return ($this->size() - $o_index);
	}
}


?>